//////////////////////////////////////////////////////////////////////////////////
//
//	Ejaculate
//		- Version 1.1
//		- 06.28.2008
//		- port: diamond-optic
//		- original: KRoT@L
//
//////////////////////////////////////////////////////////////////////////////////
//
// Information:
//
// 	- Bind a key to "ejaculate" to use
//	- Can be set to admins only
//
// Credits:
//
//   - Original plugin by KRoT@L
//   - Ported to AMXX by diamond-optic
//   - Smiley for idea/request for messages
//
// CVARs & Commands: 
//
//	amx_ejaculate "1"		//Turn ON(1) or OFF(2)
//	amx_ejaculate_admin "0"		//Admins Only - ON(1) or OFF(0)
//	amx_ejaculate_number "1"	//how many times non-admins can use per life (0 = no limit)
//
//	amx_ejaculate_msgmode "0"	//Message Modes:
//						//0 = OFF (no messages)
//						//1 = Chat message
//						//2 = Center message
//						//3 = Hud Message
//
//	amx_ejaculate_msg "$name is ejaculating!"	//Message to be printed (use $name for clients name)
//
// Extra:
//
//	Change the "#define EJAC_ADMIN	ADMIN_RESERVATION" line
//	to change the level used for admins
//
//      Put the "ejac.wav" in /sound/misc/  
//
// Changelog:
//
//	 - 06.07.2006 Version 0.1
//		Initial Port
//
//	 - 06.10.2006 Version 0.1b
//		Fixed registering the ResetHud event twice
//
//	 - 06.21.2006 Version 0.1c
//		Added cvar for how many times per life normal clients can use it
//		Admins can always use it as often as they want
//
//	 - 08.09.2006 Version 0.2
//		Fixed a typo in the CVAR & Commands section
//		Changed connect function to putinserver
//		Removed & changed some code
//
//	 - 12.09.2006 Version 0.3
//		Made it so if non-admin number is set to 0 there is no limit
//		Added is_user_alive check in make_ejaculate function
//		Removed some unused commented code
//		Uncommented client_disconnect function
//		Removed client_putinserver function
//		Added screen shake
//		Added losing stamina
//		A few other minor adjustments to the effect
//		Added CVARs to allow a message when someone is ejaculating (per req. from smiley)
//
//	 - 05.28.2007 Version 0.4
//		Blocked fullupdate command
//		Changed task id & added a define for it
//		Cleaned up code a bit...
//
//	 - 04.18.2008 Version 1.0
//		Moved version number up to 1.0
//		Updated public cvar format
//		Cleaned up the code a little bit more
//
//	 - 06.28.2008 Version 1.1
//		Replaced respawn hook with PStatus method
//		Various code improvements
//
//////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////
// Module Includes
//
#include <amxmodx>
#include <fakemeta>


///////////////////////////////////////////////////////////////////
// Version Settings
//
#define VERSION "1.1"
#define SVERSION "v1.1 - by diamond-optic (www.AvaMods.com)"


//////////////////////////////////////////////////////////////////////////////////
// Admin Level
//
#define EJAC_ADMIN	ADMIN_RESERVATION	//sets admin level


//////////////////////////////////////////////////////////////////////////////////
// Global Variables
//
new bool:EjaculateFlag[33],bool:aim[33]
new counter[33],playerJizzCount[33]
new g_msgScreenShake

//////////////////////////////////////////////////////////////////////////////////
// PCVARs
//
new p_ejaculate,p_admin,p_number,p_mode,p_msg

//////////////////////////////////////////////////////////////////////////////////
// Task ID
//
#define EJAC_TASK 68416


//////////////////////////////////////////////////////////////////////////////////
// Plugin Initialization
//
public plugin_init() 
{ 
	register_plugin("Ejaculate",VERSION,"diamond-optic")
	register_cvar("amx_ejaculate_stats",SVERSION,FCVAR_SERVER|FCVAR_SPONLY)
	
	p_ejaculate = register_cvar("amx_ejaculate","1")
	p_admin = register_cvar("amx_ejaculate_admin","0")
	p_number = register_cvar("amx_ejaculate_number","1")
	p_mode = register_cvar("amx_ejaculate_msgmode","0")
	p_msg = register_cvar("amx_ejaculate_msg","$name is ejaculating!")
	
	register_clcmd("ejaculate","ejaculate_on_player",0,"- Ejaculate...")
	
	register_event("DeathMsg","death_event","a") 

	g_msgScreenShake = get_user_msgid("ScreenShake")
	
	//Temp fix for spawning
	register_message(get_user_msgid("PStatus"),"msg_PStatus")
}

public plugin_precache()
	precache_sound("misc/ejac.wav")

////////////////////////////////////////////////////
// Temp fix for spawn hook
//
public msg_PStatus(msgid,msgdest,id)
{
	if(msgdest == 2 && !id)
		{
		new player = get_msg_arg_int(1)
		new status = get_msg_arg_int(2)
		
		if(is_user_connected(player) && status == 0)
			set_task(Float:0.1,"reset_ejaculate",player)
		}
}

public client_disconnect(id)
{
	if(get_pcvar_num(p_ejaculate) && !is_user_bot(id))
		{
		if(task_exists(EJAC_TASK+id))
			remove_task(EJAC_TASK+id)
	
		EjaculateFlag[id]=false
		playerJizzCount[id]=0
		}
}

public ejaculate_on_player(id) 
{
	if(!get_pcvar_num(p_ejaculate) || !is_user_alive(id) || EjaculateFlag[id])
		return PLUGIN_HANDLED

	new number = get_pcvar_num(p_number)
	new flags = get_user_flags(id)

	if(playerJizzCount[id] > number && number && !(flags & EJAC_ADMIN))
		return PLUGIN_HANDLED
	
	if(get_pcvar_num(p_admin) && !(flags & EJAC_ADMIN))
		{
		client_print(id,print_chat,"** YOU LACK ACCESS TO THAT COMMAND! **")
		
		return PLUGIN_HANDLED
		}
	
	new ids[1]
	
	ids[0]=id
	EjaculateFlag[id]=true
	aim[id]=false
	counter[id]=0
	
	emit_sound(id,CHAN_VOICE,"misc/ejac.wav",1.0,ATTN_NORM,0,PITCH_NORM) 
	set_task(1.5,"make_ejaculate",EJAC_TASK+id,ids,1,"a",7)
	
	playerJizzCount[id]++
	
	new msgMode = get_pcvar_num(p_mode)
	
	if(msgMode)
		{
		static msg[128]
		get_pcvar_string(p_msg,msg,127)
		
		static name[32]
		get_user_name(id,name,31)
		replace(msg,127,"$name",name)
			
		switch(msgMode)
			{
			case 1: client_print(0,print_chat,"%s",msg)
			case 2: client_print(0,print_center,"%s",msg)
			case 3: {
				set_hudmessage(255,255,255,0.02,0.73,0,6.0,8.0,0.1,0.2,4) 
				show_hudmessage(0,"%s",msg)
				}
			}
		}

	return PLUGIN_HANDLED
}

public sqrt(num) 
{ 
	new div = num 
	new result = 1 
	
	while(div > result)
		{ 
		div = (div + result) / 2 
		result = num / div 
		} 
		
	return div 
} 

public make_ejaculate(ids[]) 
{ 
	new id=ids[0]
	
	if(!get_pcvar_num(p_ejaculate) || !is_user_connected(id) || !is_user_alive(id))
		return PLUGIN_HANDLED
		
	new vec[3],aimvec[3],velocityvec[3],length 
	get_user_origin(id,vec) 
	get_user_origin(id,aimvec,3) 
	new distance = get_distance(vec,aimvec) 
	new speed = floatround(distance*random_float(1.5,2.5)) //1.9

	velocityvec[0]=aimvec[0]-vec[0] 
	velocityvec[1]=aimvec[1]-vec[1] 
	velocityvec[2]=aimvec[2]-vec[2] 

	length=sqrt(velocityvec[0]*velocityvec[0]+velocityvec[1]*velocityvec[1]+velocityvec[2]*velocityvec[2]) 

	velocityvec[0]=velocityvec[0]*speed/length 
	velocityvec[1]=velocityvec[1]*speed/length 
	velocityvec[2]=velocityvec[2]*speed/length 

	message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
	write_byte(101)
	write_coord(vec[0])
	write_coord(vec[1])
	write_coord(vec[2])
	write_coord(velocityvec[0]) 
	write_coord(velocityvec[1]) 
	write_coord(velocityvec[2]) 
	write_byte(6) // color
	write_byte(random_num(155,165)) // speed
	message_end()
	
	//shake
	message_begin(MSG_ONE_UNRELIABLE,g_msgScreenShake,{0,0,0},id)
	write_short(1<<12) //ammount 
	write_short(2<<12) //lasts this long 
	write_short(185) //frequency
	message_end()	

	//lowers stamina
	new Float:stamina
	pev(id,pev_fuser4,stamina)
	set_pev(id,pev_fuser4,stamina - 50)
	
	counter[id]++
	
	if(counter[id]==7)
		EjaculateFlag[id]=false

	return PLUGIN_CONTINUE
}

public death_event() 
{ 
   	new victim = read_data(2)

	if(get_pcvar_num(p_ejaculate) && EjaculateFlag[victim] && is_user_connected(victim) && !is_user_bot(victim)) 
		reset_ejaculate(victim)
}

public reset_ejaculate(id) 
{
	if(task_exists(EJAC_TASK+id))
		remove_task(EJAC_TASK+id)
		
	emit_sound(id,CHAN_VOICE,"misc/ejac.wav",0.0,ATTN_NORM,SND_STOP,PITCH_NORM)
	
	EjaculateFlag[id]=false
	playerJizzCount[id]=0
}
